C와 C++에서의 포인터(Pointer)

**포인터(pointer)**는 C와 C++에서 매우 중요한 개념입니다. 포인터는 메모리를 직접 제어할 수 있게 해주며, 동적 메모리 할당, 함수 인자로 참조 전달, 효율적인 자료구조 구현 등에 필수적으로 사용됩니다.

1. 포인터란 무엇인가?

예제:

int x = 42;
int *p = &x; // p는 x의 주소를 가리킴

2. 기본 문법: 주소 & 역참조(dereferencing)

주소 연산자 &

예시:

int x = 10;
printf("%p\n", &x); // x의 주소 출력 (예: 0x7ffee07dc2ac)

역참조 연산자 *

예시:

int y = 20;
int *py = &y;

printf("%d\n", *py); // 출력: 20 (y의 값)

*py = 5; // y의 값이 5로 바뀜

3. 포인터의 종류

A. 기본 포인터(Basic Pointer)

int a = 100;
int *aptr = &a; // a의 주소를 저장

B. 널 포인터 (NULL Pointer)

int *ptr = NULL; // 안전한 초기화

C. void 포인터 (Generic Pointer)

void *vptr;
int val = 12;
vptr = &val;
printf("%d\n", *(int*)vptr); // 형 변환 후 접근

D. 이중 포인터 (Pointer to Pointer)

int z = 50;
int *pz = &z;
int **ppz = &pz;

printf("%d\n", **ppz); // 출력: 50

4. 포인터 연산(Pointer Arithmetic)

예시:

int arr[5] = {1, 2, 3, 4, 5};
int *p = arr; // arr[0]을 가리킴
p++; // 이제 arr[1]을 가리킴
printf("%d\n", *p); // 출력: 2

5. 배열과 포인터

int arr[3] = {10, 20, 30};
int *p = arr;
printf("%d %d\n", arr[1], *(p + 1)); // 둘 다 20 출력

6. 함수 포인터(Function Pointer)

int add(int a, int b) { return a + b; }

int (*fnptr)(int, int) = &add;
printf("%d\n", fnptr(2, 3)); // 출력: 5

7. 동적 메모리와 포인터

C 예제:

int *p = (int*)malloc(sizeof(int));
*p = 42;
free(p);

C++ 예제:

int *p = new int(42);
delete p;

8. 구조체/클래스와 포인터

C에서 구조체 포인터 사용:

typedef struct {
    int age;
} Person;

Person p1 = {25};
Person *pperson = &p1;

printf("%d\n", pperson->age); // 25

C++ 클래스에서:

class Dog {
public:
    int age;
};

Dog d;
Dog *dp = &d;
dp->age = 5;

9. 자주 발생하는 실수 및 위험

10. C vs C++에서의 포인터 비교

항목 C C++
기본 선언 int *p; int *p;
널 포인터 사용 NULL 또는 0 nullptr (C++11), NULL
동적 메모리 할당 malloc, free new, delete, 스마트 포인터
배열과 포인터 거의 동일 C++ STL 사용 가능 (vector, 등)
스마트 포인터 직접 코드 작성 필요 unique_ptr, shared_ptr 등 있음

✅ 요약